/** 部分过滤工具方法 */

// 判断参数是否是number || string
const isNumOrStr = (val) => {
    return (typeof (val) === 'number' || typeof (val) === 'string')
}

// 保留小数位 - 默认保留0位
export const toFixedFormat = (num, fixed = 0) => {
    if (!isNumOrStr(num)) {
        return
    }

    num = typeof (num) === 'number' ? num : parseFloat(num)
    return num.toFixed(fixed)
}

// 进度转换 个 ---> 万
export const convertWan = (num, fixed = 0) => {
    if (!isNumOrStr(num)) {
        return
    }

    num = typeof (num) === 'number' ? num : parseFloat(num)
    return (num / 10000).toFixed(fixed)
}

/** 数组数据排序 - 不影响原数组
 * @param { Araay: data } 数据源
 * @param { String: sort } 排序方式
 * @param { String: field } 排序依据字段, 如果sort的排序方式是固定fixed排序时, order则是接收的固定排序值数组
 */

export const sortFormat = ({
                               data,
                               order,
                               sort = 'asc',
                               field = 'number'
                           }) => {
    if (!Array.isArray(data)) {
        return
    }

    // 深复制， 原数组存在Function则不适应此方法
    let list = JSON.parse(JSON.stringify(data))

    // 降序
    if (sort === 'desc') {
        list.sort((a, b) => (a[field] < b[field] ? 1 : -1))
        // 升序
    } else if (sort === 'asc') {
        list.sort((a, b) => (a[field] > b[field] ? 1 : -1))
        // 固定顺序
    } else if (sort === 'fixed') {
        if (!Array.isArray(order)) {
            console.log('sortFormat方法, sort参数是固定fixed排序时, order只能接收的固定排序值数组!')
            return
        }

        let temp = []
        for (let i = 0; i < order.length; i++) {
            let match = list.find(item => item[field] === order[i])
            match && temp.push(match)
        }
        list = temp
    }

    return list
}

// 格式化数字，添加逗号间隔
export function commaFormat(num) {
    if (!isNumOrStr(num)) {
        return
    }

    num = typeof (num) === 'number' ? num + '' : num
    // 切割为整数和小数
    let arr = num.split('.')
    let integer = arr[0] // 整数部分
    let float = arr[1] // 小数部分

    let result = [] // 结果集
    let counter = 0 // 计数器
    for (let i = integer.length - 1; i >= 0; i--) {
        counter++
        result.unshift(integer[i])
        if ((counter % 3) === 0 && i !== 0) {
            result.unshift(',')
        }
    }

    result = result.join('')
    result = float ? result + '.' + float : result // 累加小数部分
    return result
}

// 价格转换 - 元转分, 保证返回值是number类型
export function priceUnToCentFilter(un) {
    return parseFloat(accMul(parseFloat(un), 100))
}

// 价格转换 - 分转元, 保证返回值是number类型(目的是解决去除0结尾)
export function priceCentToUnFilter(cent, fixed = 2) {
    return parseFloat(accDiv(parseFloat(cent), 100).toFixed(fixed))
}

/** brif：js的乘法结果会有误差，在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果
 * call：accMul(arg1,arg2)
 * return：arg1乘以arg2的精确结果
 */
export function accMul(arg1, arg2) {
    let m = 0
    const s1 = arg1.toString()
    const s2 = arg2.toString()
    try {
        m += s1.split('.')[1].length
    } catch (e) {
    }
    try {
        m += s2.split('.')[1].length
    } catch (e) {
    }
    return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
}

/** brif：js的除法结果会有误差，在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果
 * call：accDiv(arg1,arg2)
 * return：arg1除以arg2的精确结果
 */
export function accDiv(arg1, arg2) {
    let t1 = 0
    let t2 = 0
    let r1, r2
    try {
        t1 = arg1.toString().split('.')[1].length
    } catch (e) {
    }
    try {
        t2 = arg2.toString().split('.')[1].length
    } catch (e) {
    }
    r1 = Number(arg1.toString().replace('.', ''))
    r2 = Number(arg2.toString().replace('.', ''))
    let intDiv = r1 / r2
    let pow = Math.pow(10, t2 - t1)
    return accMul(intDiv, pow) // 这里用上面定义好的乘法运算
}

function FloatMul(arg1, arg2) {
    var m = 0,
        s1 = arg1.toString(),//将第一个数据转换成字符出类型
        s2 = arg2.toString();//将第二个数据转换成字符出类型
    try {
        m += s1.split(".")[1].length;//截取数据的小数部分，得到小数位数
    } catch (e) {
    }
    try {
        m += s2.split(".")[1].length;//截取数据的小数部分，得到小数位数
        //将两个数据的小数位数长度相加
    } catch (e) {
    }
    var result = (Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) / Math.pow(10, m);//将两个数扩大对应的小数位数倍转换成数字类型在相乘，乘完再除于对应的扩大倍数得到最终结果
    return isNaN(result) ? 0 : result;
}

//获得两个小数相加的精确值
export function accountAdd(arg1, arg2) {
    let r1, r2, m;
    try {
        r1 = arg1.toString().split(".")[1].length;//将第一个数据转换成字符出类型，截取数据的小数部分，得到小数位数
    } catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;//将第一个数据转换成字符出类型，截取数据的小数部分，得到小数位数
    } catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2));//取出得到的最长位数，将10扩大最长位数倍
    return (FloatMul(arg1, m) + FloatMul(arg2, m)) / m;
};

export function numberFormat(value) {
    var param = {};
    var k = 10000,
        sizes = ['', '万', '亿', '万亿'],
        i;
    if (value < k) {
        param.value = value
        param.unit = ''
    } else {
        i = Math.floor(Math.log(value) / Math.log(k));

        param.value = ((value / Math.pow(k, i))).toFixed(2);
        param.unit = sizes[i];
    }
    return param.value + param.unit;
}

export default {
    isNumOrStr,
    toFixedFormat,
    convertWan,
    sortFormat,
    commaFormat,
    priceUnToCentFilter,
    priceCentToUnFilter,
    accMul,
    accDiv,
    accountAdd,
    numberFormat
}